<template>
	<view class="content">
		<!-- 过滤区，顶部搜索区 -->

		<li-form v-if="isShowSearch" :formData="searchFormData"></li-form>
		<!-- 表格内容 -->
		<view class="card table-main">
			<!-- 工具栏区 -->
			<view class="toolbar">
				<view class="title">
					<slot name="toolBarHeader">
						<text>{{toolbar.title}}</text>
					</slot>
				</view>
				<view class="right" v-if="showToolButton">
					<!-- #ifdef H5 -->
					<download-excel style="margin-right: 10px;" v-bind="toolbar.exportExcel"
					 :data="resultData">
						<el-button icon="Download" type="primary">导出数据</el-button>
					</download-excel>
					<el-button @click="clickPrint" icon="Printer" type="primary">打印</el-button>
					<!-- #endif -->
				</view>
			</view>
			<!-- 表格主体 -->
			<el-table id="dataTable" ref="tableRef" v-bind="$attrs" :height="tableHeight" :data="displayData">
				<slot />
				<template v-for="item in tableColumns">
					<!-- 首列 -->
					<el-table-column
						v-if='item.type && ["selection", "radio", "index", "expand", "sort"].includes(item.type)'
						v-bind="item">
						<template #default="scope">
							<!-- expand -->
							<template v-if="item.type == 'expand'">
								<component :is="item.render" v-bind="scope" v-if="item.render" />
								<slot v-else :name="item.type" v-bind="scope" />
							</template>
							<!-- radio -->
							<el-radio v-if="item.type == 'radio'" v-model="radio" :label="scope.row[rowKey]">
								<i></i>
							</el-radio>
							<!-- sort -->
							<el-tag v-if="item.type == 'sort'" class="move">
								<el-icon>
									<DCaret />
								</el-icon>
							</el-tag>
						</template>
					</el-table-column>
					<table-column v-if="!item.type" :item="item">
						<template #default="scope">
							<template v-if="editableRowData[scope.$index]">
								<el-input v-model="editableRowData[scope.$index][scope.column.property]"
									style="margin: 5px 0" />
							</template>
							<template v-else-if="item.editable">
								<div class="editable-cell">
									<div v-if="editableData[scope.$index]" class="editable-cell-input-wrapper">
										<el-input v-model="editableData[scope.$index][scope.column.property]"
											@pressEnter="save(scope.$index)" />
										<el-icon class="editable-cell-icon-check" @click="save(scope.$index)">
											<Check />
										</el-icon>
									</div>
									<div v-else class="editable-cell-text-wrapper">
										{{ scope.row[scope.column.property] || '-' }}
										<el-icon class="editable-cell-icon" @click="edit(scope.$index)">
											<EditPen />
										</el-icon>
									</div>
								</div>
							</template>
							<template v-else>
								{{ scope.row[scope.column.property] || '-'  }}
							</template>
						</template>
					</table-column>

					<!-- 数据列 -->
					<!-- <el-table-column v-else v-bind="item"
						:reserve-selection="item.type == 'selection'">
						<template #default="{ $index, row, column, cellIndex}">
							<template v-if="editableRowData[$index]">
								<el-input v-model="editableRowData[$index][column.property]" style="margin: 5px 0" />
							</template>
							<template v-else-if="item.editable">
								<div class="editable-cell">
									<div v-if="editableData[$index]" class="editable-cell-input-wrapper">
										<el-input v-model="editableData[$index][column.property]"
											@pressEnter="save($index)" />
										<el-icon class="editable-cell-icon-check" @click="save($index)">
											<Check />
										</el-icon>
									</div>
									<div v-else class="editable-cell-text-wrapper">
										{{ row[item.prop] || '-' }}
										<el-icon class="editable-cell-icon" @click="edit($index)">
											<EditPen />
										</el-icon>
									</div>
								</div>
							</template>
							<span v-else>{{ row[item.prop] || '-'  }}</span>
						</template>
					</el-table-column>-->
				</template>

				<!-- 操作列 -->
				<el-table-column v-bind="tableOperations" v-if="tableOperations && showAction">
					<template #default="{ $index, row, column, cellIndex}">
						<slot name="operations" :row="row">
							<span v-for="actionItem in tableOperations.actions"
								:key="actionItem.text || actionItem.icon">
								<el-button :type="actionItem.type" :link="actionItem.link" :plain="actionItem.plain"
									@click="actionItem.click(row)" :icon="actionItem.icon" size="small"
									style="margin-right: 4px">
									{{ actionItem.text }}
								</el-button>
							</span>
						</slot>
						<div class="editable-row-operations">
							<template v-if="editableRowData[$index]">
								<el-button size="small" type="success" icon="Check"
									@click="handleSave($index, row)">保存</el-button>
								<el-popconfirm title="确定取消?" confirm-button-text="确定" cancel-button-text="取消"
									@confirm="handleCancel($index)">
									<template #reference>
										<el-button size="small" icon="Close">取消</el-button>
									</template>
								</el-popconfirm>
							</template>
							<template v-else>
								<el-button size="small" icon="Edit" type="primary"
									@click="handleEdit($index, row)">编辑</el-button>
								<el-popconfirm title="你确定要删除?" confirm-button-text="确定" cancel-button-text="删除"
									@confirm="handleDelete($index, row)">
									<template #reference>
										<el-button size="small" type="danger" icon="Delete">删除</el-button>
									</template>
								</el-popconfirm>
							</template>
						</div>
					</template>
				</el-table-column>

				<!-- 插入表格最后一行之后的插槽 -->
				<template #append>
					<slot name="append" />
				</template>

			</el-table>
		</view>
		<!-- 分页器 -->
		<view class="footer">
			<slot name="footer">
				<el-pagination v-if="showPagination" background :layout="pagination.layout" :total="pagination.total"
					v-model:current-page="pagination.currentPage" v-model:page-size="pagination.pageSize"
					@change="changePagination">
				</el-pagination>
			</slot>
		</view>
	</view>
</template>

<script>
	import "./jquery3.4.1.min.js"
	import "./jQuery.print.min.js"
	import {
		cloneDeep
	} from 'lodash-es';

	import TableColumn from "./table-column.vue"
	export default {
		name: "li-table",
		emits: ['search', 'reset','saveRow', 'saveCell', 'changePagination', 'deleteRow' ],
		components: {
			TableColumn
		},
		provide() {
			return {
				liTable: this,
			}
		},
		props: {
			isShowSearch: {
				type: Boolean,
				default: true,
			},
			tableOperations: {
				type: Object,
				default () {
					return {}
				}
			},
			toolbar: {
				type: Object,
				default () {
					return {}
				}
			},
			pagination: {
				type: Object,
				default () {
					return {
						currentPage: 1,
						pageSize: 10
					}
				}
			},
			showPagination: {
				type: Boolean,
				default: true
			},
			columns: {
				type: Array,
				default () {
					return []
				}
			},
			showToolButton: {
				type: [Boolean],
				default: true
			},
			requestApi: {
				type: Function, //(params: any) => Promise<any>; // 请求表格数据的 api ==> 非必传
			},
			requestAuto: {
				type: Boolean,
				default: true,
			},
			requestError: {
				type: Function, // 表格 api 请求错误监听 ==> 非必传
			},
			dataCallback: {
				type: Function, //(data: any) => any; // 返回数据的回调函数，可以对数据进行处理 ==> 非必传
			},
			initSearchParam: {
				type: Object,
				default () {
					return {}
				}
			},
			localdata: {
				type: Array,
				default () {
					return []
				}
			},
		},
		setup(props, ctx) {
			// 透传 attribute 被暴露为 ctx.attrs
			// console.log("透传 attribute: ", ctx.attrs)
			// provide(/* 注入名 */ 'showAction', /* 值 */ this.showAction})
		},
		data() {
			return {
				//记录编辑中的单元格
				editableData: {},
				//记录编辑中的表格行
				editableRowData: {},
				//控制打印
				showAction: true,
				searchFormData: {
					model: {

					},
					config: {
						inline: true,
					},
					submitBtn: {
						txt: "搜索",
						type: "primary",
						click: this.clickSearchSubmit
					},
					resetBtn: {
						txt: "重置",
						click: this.clickSearchReset
					},
				},
				resultData: [], //网络查询的数据
				//查询表单中查询参数
				searchParam: {} ,//search form中绑定的值
				_showPagination: this.showPagination,
				tableHeight: this.$attrs.height,
			};
		},
		created() {
			this.init();
			//拉取数据
			this.requestAuto && this.query()
			let srcData = this.resultData.length == 0 ? this.localdata : this.resultData;
			this.pagination.total = srcData.length;
		},
		computed: {
			tableColumns() {
				return this.columns;
			},
			displayData() {
				/*
				如果是只有本地数据，	如果有网络数据只显示网络数据
				*/
				
				if (!this._showPagination) {
					return this.resultData
				}

				return this.resultData.slice(
					(this.pagination.currentPage - 1) * this.pagination.pageSize,
					this.pagination.pageSize * this.pagination.currentPage
				);
			}
		},
		watch: {
			localdata: {
				immediate: true,
				handler(val, old) {
					if (Array.isArray(val) && old !== val) {
						this.resultData = val
					}
				}
			},
			// resultData: {
			// 	immediate: true,
			// 	handler(val) {
			// 		if (val.length) {

			// 		}
			// 	}
			// }
		},
		beforeUpdate() {
			this.$nextTick(() => {
				this.$refs.tableRef.doLayout()
			})
		},

		methods: {
			init() {
				this.searchFormData.items = [];
				this.getSearchFormItems(this.columns);
			},
			getSearchFormItems(columns){
				columns.forEach((item) => {
					if(item.subColumns && item.subColumns.length){
						return this.getSearchFormItems(item.subColumns)
					}
					if (item.search) {
						let val = {
							label: item.label,
							prop: item.prop,
							...item.search,
						};
						this.searchFormData.items.push(val);
						let defaultVal = item.search.defaultVal || null;
						this.searchFormData.model[item.prop] = defaultVal;
					}
				})
			},
			
			//操作单元格
			save(index) {
				let oldData = this.displayData[index];
				let newData = this.editableData[index];
				Object.assign(this.displayData[index], this.editableData[index]);
				this.$emit("saveCell", oldData, newData)
				delete this.editableData[index];
			},
			edit(index) {
				this.editableData[index] = cloneDeep(this.displayData[index]);
			},
			//操作表格行
			handleEdit(index, row) {
				//如果在编辑单元格的处理
				this.editableRowData[index] = cloneDeep(this.displayData[index]);
			},
			handleDelete(index, row) {
				let oldData = this.displayData[index];
				let newData = this.editableRowData[index];
				this.resultData = this.resultData.filter(item => item.key !== row.key);
				this.$emit("deleteRow", oldData, newData)
				delete this.editableRowData[index];
			},
			handleSave(index, row) {
				let oldData = this.displayData[index];
				let newData = this.editableRowData[index];
				Object.assign(this.displayData[index], this.editableRowData[index]);
				this.$emit("saveRow", oldData, newData);
				delete this.editableRowData[index];
			},
			handleCancel(index, row) {
				delete this.editableRowData[index];
			},
			clickPrint() {
				this.showAction = false;
				// this._showPagination = false;
				// this.tableHeight = "-";
				let _this = this;
				this.$nextTick(() => {
					this.$refs.tableRef.doLayout()
					// #ifdef H5
					$("#dataTable").print({
						addGlobalStyles: true,
						stylesheet: null,
						rejectWindow: true,

						/*
						Default: null, uses the host page title
						Acceptable-Values: Any single-line string
						Function: To change the printed title
						*/
						title: "null",
						noPrintSelector: ".no-print",
						iframe: true,
						//Add this on top
						// prepend: "Hello World!!!<br/>",
						prepend: "",
						//Add this on bottom
						// append: "<span><br/>Buh Bye!</span>",
						append: "",
						//Log to console when printing is done via a deffered callback
						deferred: $.Deferred().done(function() {
							console.log('Printing done', arguments);
							_this.showAction = true;
							_this._showPagination = true
						})
					});
					// #endif
				})
			},
			clickSearchSubmit() {
				this.search()
				this.$emit("search")
			},
			clickSearchReset() {
				this.reset()
				this.$emit("reset")
			},
			async query() {
				// if (!this.requestApi) return;
				try {
					// 先把初始化参数和分页参数放到总参数里面
					let queryParam = {
						...this.initSearchParam,
						currentPage: this.pagination.currentPage,
						pageSize: this.pagination.pageSize,

					};
					for (let key in this.searchFormData.model) {
						if (this.searchFormData.model[key] != null) {
							queryParam[key] = this.searchFormData.model[key]
						}
					}
					// console.log("queryParam:", queryParam);
					return
					let {
						data
					} = await this.requestApi(queryParam);
					this.dataCallBack && (data = this.dataCallBack(data));
					this.resultData = this._showPagination ? data.list : data;
					// 解构后台返回的分页数据 (如果有分页更新分页信息)
					if (this._showPagination) {
						const {
							currentPage,
							pageSize,
							total
						} = data;
						this.updatePagintion({
							currentPage,
							pageSize,
							total
						});
					}
				} catch (err) {
					console.log(err);
					if(this.requestError){
						this.requestError(err)
					}
				}
			},
			search() {
				this.pagination.currentPage = 1;
				this.query();
			},
			reset() {
				this.pagination.currentPage = 1;
				this.query();
			},
			updatePagintion(data) {
				Object.assign(this.pagination, data);
			},
			changePagination(currentPage, pageSize) {
				this.$emit("changePagination", currentPage, pageSize);
			},
		}
	}
</script>

<style lang="scss" scoped>
	.editable-cell {
		position: relative;

		.editable-cell-input-wrapper,
		.editable-cell-text-wrapper {
			padding-right: 24px;
		}

		.editable-cell-text-wrapper {
			padding: 5px 24px 5px 5px;
		}

		.editable-cell-icon,
		.editable-cell-icon-check {
			position: absolute;
			right: 0;
			width: 20px;
			cursor: pointer;
		}

		.editable-cell-icon {
			margin-top: 4px;
			display: none;
		}

		.editable-cell-icon-check {
			line-height: 28px;
		}

		.editable-cell-icon:hover,
		.editable-cell-icon-check:hover {
			color: #108ee9;
		}

		.editable-add-btn {
			margin-bottom: 8px;
		}
	}

	.editable-cell:hover .editable-cell-icon {
		display: inline-block;
	}

	.editable-row-operations {
		display: flex;
		// justify-content: space-between;
		flex-wrap: wrap;
		flex-direction: row;
		justify-content: center;

		.el-button {
			margin-right: 8rpx;
			margin-top: 2px;
			margin-bottom: 2px;
		}

		::v-deep .el-button+.el-button {
			margin-left: 0px !important;
		}
	}

	.header {
		margin-bottom: 10px;
	}

	::v-deep {
		.el-pagination button {
			background: var(--el-pagination-bg-color) !important;
		}

		// .el-button+.el-button  {
		// 	margin-left: 0px !important;
		// }
	}

	.footer {
		display: flex;
		flex-direction: row;
		margin-top: 10px;
		justify-content: center;
	}

	@media print {
		.no-print {
			display: none;
		}

		/* 这里定义了一个名为"no-print"的class */

		/* 如果想同时隐藏所有元素（包括内容），则可以使用以下代码 */
		// body * { visibility: hidden !important; }
	}

	.table-main {
		display: flex;
		flex: 1;
		flex-direction: column;
		width: 100%;
		height: 100%;

		.toolbar {
			margin-bottom: 5px;

			.title {
				display: flex;
				flex-direction: row;
				flex-wrap: wrap;
				float: left;
			}

			.right {
				display: flex;
				flex-direction: row;
				float: right;
			}

			.el-button {
				margin-bottom: 15px;
			}
		}
	}
</style>